#ifndef __CXXCALL_TESTS_CALLOUT__
#define __CXXCALL_TESTS_CALLOUT__   1

#include "../cxxcall.hpp"
#include "utils.hpp"

namespace callout
{

template <class ...Args>
void test_sum_helper (Args... args)
{
  typedef typename sum_type<Args...>::type Rtype;
  auto fn = (Rtype (*) (Args...))sum<Args...>;
  auto v = cxxcall::make_av_static (fn);
  auto tup = TUPLE (args...);
  
  global_tuple = new decltype (tup) (tup);
  using helper_type = int[];
  helper_type { 0, (v.arg (args), 0)... };
  v.call ();

  ASSERT (equal<decltype (fn (args...))>::eq (v.av.raddr, fn, args...));
  delete ((decltype (&tup)) global_tuple);
}

#define test_sum(suffix)   \
  test_sum_helper (CONCAT (42, suffix));   \
  test_sum_helper (CONCAT (-77, suffix), CONCAT (78, suffix));   \
  test_sum_helper (CONCAT (-101, suffix), CONCAT (102, suffix),   \
                   CONCAT (-103, suffix));   \
  \
  test_sum_helper (CONCAT (211, suffix), CONCAT (-212, suffix),   \
                   CONCAT (213, suffix), CONCAT (-214, suffix));   \
  \
  test_sum_helper (CONCAT (306, suffix), CONCAT (-307, suffix),   \
                   CONCAT (308, suffix), CONCAT (-309, suffix),   \
                   CONCAT (310, suffix));   \
  \
  test_sum_helper (CONCAT (-451, suffix), CONCAT (452, suffix),   \
                   CONCAT (-453, suffix), CONCAT (454, suffix),   \
                   CONCAT (-455, suffix), CONCAT (456, suffix));   \
  \
  test_sum_helper (CONCAT (-523, suffix), CONCAT (524, suffix),   \
                   CONCAT (-525, suffix), CONCAT (526, suffix),   \
                   CONCAT (-527, suffix), CONCAT (528, suffix),   \
                   CONCAT (-529, suffix));   \
  \
  test_sum_helper (CONCAT (678, suffix), CONCAT (-679, suffix),   \
                   CONCAT (680, suffix), CONCAT (-681, suffix),   \
                   CONCAT (682, suffix), CONCAT (-683, suffix),   \
                   CONCAT (684, suffix), CONCAT (-685, suffix));   \
  \
  test_sum_helper (CONCAT (7, suffix), CONCAT (-8, suffix),   \
                   CONCAT (9, suffix), CONCAT (-10, suffix),   \
                   CONCAT (11, suffix), CONCAT (-12, suffix),   \
                   CONCAT (13, suffix), CONCAT (-14, suffix),   \
                   CONCAT (15, suffix))

void test_static ()
{
#undef SUFFIX
#define SUFFIX
  test_sum (SUFFIX);

#undef SUFFIX
#define SUFFIX   ll
  test_sum (SUFFIX);

#undef SUFFIX
#define SUFFIX .1f
  test_sum (SUFFIX);

#undef SUFFIX
#define SUFFIX   .1
  test_sum (SUFFIX);

#undef SUFFIX
#define SUFFIX   .1l
  test_sum (SUFFIX);

#undef test_sum
}

test_module callout_tests
{
  "callout",
  {
    { "static callouts", test_static }
  }
};

} // namespace callout

#endif
